"""
Case Type   : 资源池化故障模式库
Case Name   : pg_hba.conf文件无读权限-pg_hba.conf文件无读写权限
Create At   : 2025/05
Owner       : haomeng
Description :
    1、查看集群状态
    2、运行tpcc业务
    3、修改主节点pg_hba.conf配置文件权限为不可用
    4、查看业务运行情况
    5、重启集群
    6、恢复原pg_hba.conf配置文件权限
    7、拉起被踢出节点
    8、查看集群状态
Expect      :
    1、集群状态正常
    2、运行业务成功
    3、修改主节点pg_hba.conf配置文件权限成功
    4、业务运行正常无影响
    5、重启集群失败，原主节点被踢出
    6、恢复原pg_hba.conf文件权限成功
    7、启动集群成功
    8、集群状态正常
History     :
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.ComThread import ComThread
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

class SSFauleMode(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.user_node = [Node(node='PrimaryRoot'), Node(node='PrimaryDbUser')]
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.com = Common()
        self.constant = Constant()
        self.conf_file = os.path.join(macro.DB_INSTANCE_PATH, macro.PG_HBA_FILE_NAME)

    def test_ss_faule(self):
        text = '-----step1:查看集群状态;  expect:集群状态正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('Normal', status, '集群状态异常')

        text = '-----step2:执行tpcc读写业务  expect:业务执行成功-----'
        self.log.info(text)

        tpcc_cmd = f'./runBenchmark.sh {macro.PROPS_FILENAME}'
        self.log.info(tpcc_cmd)

        tpcc_execute = ComThread(self.com.start_tpcc, args=(self.user_node[0],
                                                               f'{macro.TPCC_PATH}',
                                                               tpcc_cmd))
        tpcc_execute.setDaemon(True)
        tpcc_execute.start()

        text = '-----step3:修改主节点pg_hba.conf文件权限为不可用  expect:修改成功-----'
        self.log.info(text)

        delete = f'chmod 000 {self.conf_file};' \
                 f'cat {self.conf_file};'
        self.log.info(delete)

        delete_execute = ComThread(self.com.get_sh_result, args=(self.user_node[1], delete))
        delete_execute.setDaemon(True)
        delete_execute.start()

        text = '-----step4:查看业务运行情况  expect:业务运行正常无影响-----'
        self.log.info(text)

        tpcc_execute.join(10 * 60)
        ret1 = tpcc_execute.get_result()
        self.log.info(ret1)
        self.assertIn('Session End', ret1, 'tpcc执行失败')

        delete_execute.join(10 * 60)
        ret2 = delete_execute.get_result()
        self.log.info(ret2)
        self.assertIn('Permission denied', ret2, '修改pg_hba.conf文件权限失败')

        text = '-----step5:重启集群  expect:重启失败，原主节点被踢出，集群内产生新的主节点-----'
        self.log.info(text)

        restart = self.pri_sh.exec_cm_ctl('stop;', 'cm_ctl start -t 30')
        self.log.info(restart)
        self.assertIn(self.constant.cm_stop_success_msg, restart, '停止集群失败')
        self.assertIn(self.constant.cm_start_failed_msg, restart, '启动集群成功')

        time.sleep(30)
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertNotIn('cluster_state  ：Normal', status, '集群状态正常')
        self.assertIn('S Primary', status, '集群状态异常')

    def tearDown(self):
        text = '-----step6:恢复原pg_hba.conf文件权限  expect:恢复成功-----'
        self.log.info(text)

        mv = f'chmod 600 {self.conf_file};' \
             f'cat {self.conf_file} | grep {self.user_node[1].ssh_host};'
        self.log.info(mv)
        mv_execute = self.user_node[1].sh(mv).result()
        self.log.info(mv_execute)

        text = '-----step7:拉起被踢出节点  expect:启动成功-----'
        self.log.info(text)

        start = self.pri_sh.exec_cm_ctl('start')
        self.log.info(start)

        text = '-----step8:查看集群状态  expect:集群状态正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)

        if 'P Primary' not in status:
            seitch = self.pri_sh.exec_cm_ctl('switchover', '-a')
            self.log.info(seitch)

        time.sleep(60)
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.assertIn('Normal', status, '集群状态异常')
        self.assertIn('P Primary', status.splitlines()[-1], '集群状态异常')
        self.assertIn(f'{self.user_node[1].ssh_host}', mv_execute, '恢复配置文件失败')
        self.assertIn(self.constant.cm_start_success_msg, start, '启动集群失败')
        self.log.info(f'----{os.path.basename(__file__)} end----')
